﻿//=================================MedianHistogramAlgorithm.cs==========================\\
//===Bart Steijlen======\\



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;

namespace Team2_Vision
{
    class Median : VisionAlgorithm
    {
        public Median(String name) : base(name) { }
        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage, int matrix)
        {

            Bitmap returnImage = new Bitmap(sourceImage);
            BitmapData sourceImageData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData returnImageData = returnImage.LockBits(new Rectangle(0, 0, returnImage.Width, returnImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            IntPtr adressreturn = returnImageData.Scan0;
            IntPtr adresssource = sourceImageData.Scan0;

            int arraygrootte = sourceImage.Width * sourceImage.Height *3;
           
            int midden = (matrix / 2);
            int teller = 0;
            int median = 0;
            byte[] array_from_source = new byte[arraygrootte];
            byte[] array_red = new byte[arraygrootte/3];
            byte[] array_back = new byte[arraygrootte];
            int[] histogram = new int[256];

           
            Marshal.Copy(adresssource, array_from_source, 0, arraygrootte);

            //maak een array met alle rode waardes;

            for (int i = 0; i < arraygrootte / 3; i++)
            {
                array_red[i] = (byte)((array_from_source[i * 3] + array_from_source[i * 3 + 1] + array_from_source[i * 3+ 2])/3);
            }
            

         
            //zeker weten dat de histogram leeg is
            for (int i = 0; i <256; i++)
            {
                histogram[i] = 0;
            }

            //select pixel
            for (int y = midden; y < sourceImage.Height-midden; y++)
            {
                for (int x = midden; x < sourceImage.Width-midden; x++)
                {
                    //=sneller dan for(int i = 0; i < 256; i++){histogram[i]=0;}
                    histogram = new int[256];         
                    
                    //matrix selecteren en schrijven naar histogram
                    for (int my = -midden; my <= midden; my++)
                    {
                        for (int mx = -midden; mx <= midden; mx++)
                        {
                            teller = array_red[(((y+my) * sourceImage.Width) + x + mx)];
                            histogram[teller]++;                           
                        }
                    }
                    //median kiezen
                    median = 0;
                    for (int i = 0; i <= 255; i++)
                    {
                        median = median + histogram[i];
                        if (median >= midden)
                        {
                            median = i;

                            break;
                        }
                    }
                    //median terug zetten
                    array_back[((y * sourceImage.Width * 3) + x*3)] = (byte)median;
                    array_back[((y * sourceImage.Width * 3) + x*3) + 1]  = (byte)median;
                    array_back[((y * sourceImage.Width * 3) + x*3) + 2] = (byte)median;
                }
            }           
            
            Marshal.Copy(array_back, 0, returnImageData.Scan0, arraygrootte);
            returnImage.UnlockBits(returnImageData);
            sourceImage.UnlockBits(sourceImageData);
            return returnImage;
        }

        static int[] clear()
        {
            int[] array = new int[256];

            return array;
        }

    }

}




